﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Innova.Microfinanzas.BusinessEntities;
using Innova.Microfinanzas.BusinessEntities.EnumClassifiers;
using MyCommerce.Business.GeneralParameters;
using Innova.Microfinanzas.BusinessEntities.SystemEnums;
using System.Data;
using System.Data.Objects.DataClasses;

namespace MyCommerce.Business.Stores
{
    public class OrderSupplierManager
    {
        private MyCommerceEntities vContext;

        public OrderSupplierManager()
        {
            if (vContext == null)
            {
                vContext = new MyCommerceEntities();
                vContext.ContextOptions.LazyLoadingEnabled = false;
            }
        }

        public OrderSupplierManager(bool lazyLoad)
        {
            if (vContext == null)
            {
                vContext = new MyCommerceEntities();
                vContext.ContextOptions.LazyLoadingEnabled = lazyLoad;
            }
        }

        public OrderSupplier GetOrdersById(long idOrder)
        {
            var vResult = (from os in vContext.OrderSupplier
                           where os.IdOrderSupplier == idOrder
                           select os).FirstOrDefault();

            return vResult;
        }

        public List<OrderSupplier> GetOrdersByIdStoreAndUser(long idStore, long idUser)
        {
            List<OrderSupplier> colOrders = new List<OrderSupplier>();

            long cancelState = Convert.ToInt64(OrderSupplierState.Cancel);
            var vResult = (from os in vContext.OrderSupplier
                           .Include("Supplier")
                           .Include("Classifier")
                           .Include("Classifier1")
                           where os.IdcOrderState != cancelState && os.IdStore == idStore && os.IdUser == idUser
                           select os);
            if (vResult != null)
                colOrders = new List<OrderSupplier>(vResult.AsEnumerable<OrderSupplier>());

            return colOrders;
        }

        public void CancelOrderSupplier(long idOrder)
        {
            var vResult = (from os in vContext.OrderSupplier
                           where os.IdOrderSupplier == idOrder
                           select os).First();
            if (vResult != null)
            {
                if (vResult.IdcOrderState != Convert.ToInt64(OrderSupplierState.Request))
                    throw new Exception("Solo se pueden anular ordenes en estado solicitado.");
                if (vResult.IdcOrderState == Convert.ToInt64(OrderSupplierState.Cancel))
                    throw new Exception("La orden de pedido se encuentra anulada.");

                vResult.IdcOrderState = Convert.ToInt64(OrderSupplierState.Cancel);
            }
            vContext.SaveChanges();
        }

        public void CreateOrderSupplier(IList<long> colSelectedConveyors, long idStore, long idUser, long idSupplier, long idMoney, DataTable dtOrderDetail)
        {
            CompositionOfCodeManager codeMgr = new CompositionOfCodeManager();

            OrderSupplier objOrder = OrderSupplier.CreateOrderSupplier(0, idStore, idUser,
                System.DateTime.Now, codeMgr.GenerateCode(CompositionOfCodeTypes.OrderToSupplierCode, idStore),
                idSupplier, Convert.ToInt64(OrderSupplierState.Request), 0, idMoney, 0, 0);

            decimal totalOthers = 0;
            decimal totalProducts = 0;
            foreach (long idConveyor in colSelectedConveyors)
            {
                SubOrderSupplier objSubOrder = SubOrderSupplier.CreateSubOrderSupplier(0, 0, idConveyor, Convert.ToInt64(OrderSupplierState.Request));                
                foreach (DataRow objRowItem in dtOrderDetail.Rows)
                {
                    if (Convert.ToInt32(objRowItem[":CCV:" + idConveyor.ToString()]) > 0)
                    {
                        OrderProductDetail objNewDetail = OrderProductDetail.CreateOrderProductDetail(0, Convert.ToInt64(objRowItem["IdProduct"])
                            , 0, Convert.ToInt32(objRowItem[":CCV:" + idConveyor.ToString()]), Convert.ToDecimal(objRowItem["UnitPrice"]) * Convert.ToDecimal(objRowItem[":CCV:" + idConveyor.ToString()])
                            , Convert.ToDecimal(objRowItem["UnitPrice"]), Convert.ToDecimal(objRowItem[":PTCV:" + idConveyor.ToString()])
                            , Convert.ToDecimal(objRowItem[":TCV:" + idConveyor.ToString()]));
                        totalProducts += objNewDetail.TotalPrice;
                        totalOthers += objNewDetail.TotalOtherPrice;                        
                        objSubOrder.OrderProductDetail.Add(objNewDetail);
                    }
                }
                objOrder.SubOrderSupplier.Add(objSubOrder);
            }

            objOrder.TotalProducts = totalProducts;
            objOrder.TotalOthers = totalOthers;
            objOrder.TotalOrder = totalProducts + totalOthers;
            vContext.OrderSupplier.AddObject(objOrder);
            vContext.SaveChanges();
        }

        public void SaveOrderDelivery(long idOrder, DataTable dtToSave)
        {
            var vOrderToDelivery = (from os in vContext.OrderSupplier
                                    where os.IdOrderSupplier == idOrder
                                    select os).FirstOrDefault();

            if (vOrderToDelivery != null)
            {
                List<DeliveryStockDetail> colDeliveryDetail = new List<DeliveryStockDetail>();
                Dictionary<long, Dictionary<long, long>> dicDeliveryRelation = new Dictionary<long, Dictionary<long, long>>();
                if (vOrderToDelivery.SubOrderSupplier != null
                    && vOrderToDelivery.SubOrderSupplier.Count > 0)
                {
                    bool withLessDelivery = false;
                    List<long> colIdConveyors = new List<long>();
                    foreach (var objSubOrder in vOrderToDelivery.SubOrderSupplier)
                    {
                        if (!dicDeliveryRelation.ContainsKey(objSubOrder.IdConveyor))
                        {
                            dicDeliveryRelation.Add(objSubOrder.IdConveyor, new Dictionary<long, long>());
                            colIdConveyors.Add(objSubOrder.IdConveyor);
                        }
                        if (objSubOrder.OrderProductDetail != null
                            && objSubOrder.OrderProductDetail.Count > 0)
                        {
                            foreach (var objDetail in objSubOrder.OrderProductDetail)
                            {
                                dicDeliveryRelation[objSubOrder.IdConveyor].Add(objDetail.IdProduct, objDetail.IdOrderProductDetail);
                            }
                        }
                    }
                    foreach (DataRow objRow in dtToSave.Rows)
                    {
                        foreach (var idConveyor in colIdConveyors)
                        {
                            long idProduct = Convert.ToInt64(objRow["IdProduct"]);
                            int totalDelivery = Convert.ToInt32(objRow[":CCV:" + idConveyor.ToString()]);
                            int deliveryPastQuantity = Convert.ToInt32(objRow[":CECV:" + idConveyor.ToString()]);
                            int deliveryNew = Convert.ToInt32(objRow[":CNECV:" + idConveyor.ToString()]);
                            if ((deliveryNew + deliveryPastQuantity) < totalDelivery)
                                withLessDelivery = true;
                            if (deliveryNew > 0)
                            {
                                OrderDelivery newDelivery = OrderDelivery.CreateOrderDelivery(0, dicDeliveryRelation[idConveyor][idProduct], deliveryNew, System.DateTime.Today);
                                vContext.AddToOrderDelivery(newDelivery);

                                //agregamos el detalle para ingresar a almacenes
                                DeliveryStockDetail objDelivery = colDeliveryDetail.Find(objFilter => objFilter.IdProduct == idProduct);
                                if (objDelivery != null)
                                    objDelivery.Quantity += deliveryNew;
                                else
                                {
                                    objDelivery = new DeliveryStockDetail();
                                    objDelivery.IdProduct = idProduct;
                                    objDelivery.IdStore = vOrderToDelivery.IdStore;
                                    objDelivery.IdSuplier = vOrderToDelivery.IdSupplier;
                                    objDelivery.Quantity = deliveryNew;
                                    colDeliveryDetail.Add(objDelivery);
                                }
                            }
                        }
                    }

                    if (withLessDelivery)
                        vOrderToDelivery.IdcOrderState = Convert.ToInt64(OrderSupplierState.ParcialDelivery);
                    else
                    {
                        vOrderToDelivery.IdcOrderState = Convert.ToInt64(OrderSupplierState.Delivery);
                    }

                    ProductStockManager stockMgr = new ProductStockManager(true);
                    stockMgr.SaveProductStockFromDelivery(colDeliveryDetail);
                    vContext.SaveChanges();
                }
            }
        }
    }
}
